// src/tests/run-tests.js
// 简单的测试运行脚本

import { getBranchList, getBranchById, getAllMembers, createBranch, updateBranch, deleteBranch, transferMemberRelations, exportBranchData } from '../api/branch.js';

// 简单的测试框架
class TestRunner {
  constructor() {
    this.tests = [];
    this.passed = 0;
    this.failed = 0;
  }

  test(name, testFn) {
    this.tests.push({ name, testFn });
  }

  async run() {
    console.log('🚀 开始运行党支部管理功能测试...\n');

    for (const { name, testFn } of this.tests) {
      try {
        await testFn();
        console.log(`✅ ${name}`);
        this.passed++;
      } catch (error) {
        console.log(`❌ ${name}`);
        console.log(`   错误: ${error.message}\n`);
        this.failed++;
      }
    }

    console.log(`\n📊 测试结果: ${this.passed} 通过, ${this.failed} 失败`);
    console.log(`📈 成功率: ${((this.passed / (this.passed + this.failed)) * 100).toFixed(2)}%`);
  }

  assert(condition, message) {
    if (!condition) {
      throw new Error(message || '断言失败');
    }
  }

  assertEqual(actual, expected, message) {
    if (actual !== expected) {
      throw new Error(message || `期望 ${expected}, 但得到 ${actual}`);
    }
  }

  assertNotEqual(actual, expected, message) {
    if (actual === expected) {
      throw new Error(message || `期望不等于 ${expected}, 但得到 ${actual}`);
    }
  }

  assertNotNull(value, message) {
    if (value === null || value === undefined) {
      throw new Error(message || '期望值不为 null 或 undefined');
    }
  }

  assertArray(value, message) {
    if (!Array.isArray(value)) {
      throw new Error(message || '期望值为数组');
    }
  }
}

// 创建测试运行器
const runner = new TestRunner();

// API 测试
runner.test('获取党支部列表', async () => {
  const result = await getBranchList({
    page: 1,
    pageSize: 10,
    search: '',
    branchType: null
  });

  runner.assertNotNull(result, '结果不应为 null');
  runner.assertArray(result.list, '列表应为数组');
  runner.assert(result.list.length <= 10, '列表长度应不超过页面大小');
  runner.assertEqual(typeof result.total, 'number', '总数应为数字');
});

runner.test('按关键词搜索党支部', async () => {
  const result = await getBranchList({
    page: 1,
    pageSize: 10,
    search: '软件工程',
    branchType: null
  });

  runner.assertArray(result.list, '列表应为数组');
  runner.assert(
    result.list.every(branch => 
      branch.branchName.includes('软件工程') || 
      (branch.branchDescription && branch.branchDescription.includes('软件工程'))
    ),
    '所有结果应包含搜索关键词'
  );
});

runner.test('按支部类型筛选', async () => {
  const result = await getBranchList({
    page: 1,
    pageSize: 10,
    search: '',
    branchType: '硕士'
  });

  runner.assertArray(result.list, '列表应为数组');
  runner.assert(
    result.list.every(branch => branch.branchType === '硕士'),
    '所有结果应为硕士党支部'
  );
});

runner.test('创建新党支部', async () => {
  const newBranchData = {
    branchName: '测试党支部',
    branchType: '本科',
    branchDescription: '这是一个测试党支部'
  };

  const result = await createBranch(newBranchData);

  runner.assertNotNull(result, '结果不应为 null');
  runner.assertNotNull(result.branchId, '应生成党支部ID');
  runner.assertEqual(result.branchName, newBranchData.branchName, '党支部名称应匹配');
  runner.assertEqual(result.branchType, newBranchData.branchType, '党支部类型应匹配');
  runner.assertEqual(result.branchDescription, newBranchData.branchDescription, '党支部描述应匹配');
});

runner.test('获取党支部详情', async () => {
  // 先创建一个党支部
  const createdBranch = await createBranch({
    branchName: '详情测试党支部',
    branchType: '博士',
    branchDescription: '用于测试详情功能的党支部'
  });

  const result = await getBranchById(createdBranch.branchId);

  runner.assertNotNull(result, '结果不应为 null');
  runner.assertEqual(result.branchId, createdBranch.branchId, '党支部ID应匹配');
  runner.assertEqual(result.branchName, createdBranch.branchName, '党支部名称应匹配');
  runner.assertArray(result.currentMembersDetails, '当前成员详情应为数组');
});

runner.test('更新党支部信息', async () => {
  // 先创建一个党支部
  const createdBranch = await createBranch({
    branchName: '更新测试党支部',
    branchType: '本科',
    branchDescription: '原始描述'
  });

  const updateData = {
    branchName: '更新后的党支部名称',
    branchDescription: '更新后的描述'
  };

  const result = await updateBranch(createdBranch.branchId, updateData);

  runner.assertNotNull(result, '结果不应为 null');
  runner.assertEqual(result.branchName, updateData.branchName, '党支部名称应已更新');
  runner.assertEqual(result.branchDescription, updateData.branchDescription, '党支部描述应已更新');
});

runner.test('删除党支部', async () => {
  // 先创建一个党支部
  const createdBranch = await createBranch({
    branchName: '待删除党支部',
    branchType: '硕士',
    branchDescription: '这个党支部将被删除'
  });

  const deleteResult = await deleteBranch(createdBranch.branchId);
  runner.assert(deleteResult, '删除操作应成功');

  // 验证删除后无法找到该党支部
  const deletedBranch = await getBranchById(createdBranch.branchId);
  runner.assertEqual(deletedBranch, null, '删除后应无法找到党支部');
});

runner.test('获取所有成员列表', async () => {
  const result = await getAllMembers();

  runner.assertArray(result, '结果应为数组');
  runner.assert(result.length > 0, '列表不应为空');
  runner.assertNotNull(result[0].memberId, '成员应有ID');
  runner.assertNotNull(result[0].memberName, '成员应有姓名');
});

runner.test('转移党员组织关系', async () => {
  // 创建两个党支部
  const fromBranch = await createBranch({
    branchName: '转出党支部',
    branchType: '本科',
    branchDescription: '党员将从这个党支部转出'
  });

  const toBranch = await createBranch({
    branchName: '转入党支部',
    branchType: '硕士',
    branchDescription: '党员将转入这个党支部'
  });

  // 模拟一些成员ID
  const memberIds = ['member-1', 'member-2'];

  const transferData = {
    memberIds,
    fromBranchId: fromBranch.branchId,
    toBranchId: toBranch.branchId,
    transferStartDate: '2024-01-01'
  };

  const result = await transferMemberRelations(transferData);
  runner.assert(result, '转移操作应成功');
});

runner.test('导出党支部数据', async () => {
  // 先创建一个党支部
  const createdBranch = await createBranch({
    branchName: '导出测试党支部',
    branchType: '博士',
    branchDescription: '用于测试导出功能的党支部'
  });

  const result = await exportBranchData(createdBranch.branchId);

  runner.assertNotNull(result, '结果不应为 null');
  runner.assertEqual(result.branchId, createdBranch.branchId, '党支部ID应匹配');
  runner.assertNotNull(result.exportTime, '应有导出时间');
  runner.assertEqual(result.exportedBy, '系统管理员', '导出者应为系统管理员');
});

// 错误处理测试
runner.test('处理不存在的党支部ID', async () => {
  const result = await getBranchById('non-existent-id');
  runner.assertEqual(result, null, '不存在的ID应返回null');
});

runner.test('处理无效的更新操作', async () => {
  const result = await updateBranch('non-existent-id', { branchName: '测试' });
  runner.assertEqual(result, null, '不存在的ID更新应返回null');
});

runner.test('处理无效的删除操作', async () => {
  const result = await deleteBranch('non-existent-id');
  runner.assertEqual(result, false, '不存在的ID删除应返回false');
});

runner.test('处理无效的导出操作', async () => {
  const result = await exportBranchData('non-existent-id');
  runner.assertEqual(result, null, '不存在的ID导出应返回null');
});

// 性能测试
runner.test('API响应时间测试', async () => {
  const startTime = Date.now();
  
  await getBranchList({
    page: 1,
    pageSize: 20,
    search: '',
    branchType: null
  });
  
  const endTime = Date.now();
  const responseTime = endTime - startTime;
  
  runner.assert(responseTime < 2000, `API响应时间应小于2秒，实际: ${responseTime}ms`);
});

// 数据一致性测试
runner.test('数据一致性测试', async () => {
  // 创建党支部
  const createdBranch = await createBranch({
    branchName: '一致性测试党支部',
    branchType: '本科',
    branchDescription: '用于测试数据一致性'
  });

  // 获取列表
  const list = await getBranchList({ page: 1, pageSize: 50 });
  
  // 验证创建的党支部在列表中
  const foundInList = list.list.some(branch => branch.branchId === createdBranch.branchId);
  runner.assert(foundInList, '创建的党支部应在列表中');

  // 获取详情
  const detail = await getBranchById(createdBranch.branchId);
  runner.assertEqual(detail.branchName, createdBranch.branchName, '详情中的名称应与创建时一致');
  runner.assertEqual(detail.branchType, createdBranch.branchType, '详情中的类型应与创建时一致');
});

// 运行所有测试
runner.run().then(() => {
  console.log('\n🎉 测试完成！');
}).catch(error => {
  console.error('❌ 测试运行失败:', error);
});

// 导出运行器以便在其他文件中使用
export { runner };